package com.liy.cloud.common.pw.service.impl;

import com.liy.cloud.common.pw.dao.PwSellerReportDao;
import com.liy.cloud.common.pw.entity.PwAccountListEntity;
import com.liy.cloud.common.pw.entity.PwAccountMainEntity;
import com.liy.cloud.common.pw.entity.PwSellerReportDetailEntity;
import com.liy.cloud.common.pw.entity.PwSellerReportEntity;
import com.liy.cloud.common.pw.service.PwAccountListService;
import com.liy.cloud.common.pw.service.PwAccountMainTicketMoneyService;
import com.liy.cloud.common.pw.service.PwSellerReportService;
import com.liy.cloud.common.pw.service.SellerReportDetailService;
import com.das.framework.common.dao.IBaseDao;
import com.das.framework.common.extvo.ResultVO;
import com.das.framework.common.service.impl.BaseServiceImpl;
import com.das.framework.common.utils.DateUtil;
import com.das.framework.common.utils.Tools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 售票员结算单主表 Service接口服务实现
 *
 * @author
 * @ClassName: PwSellerReportServiceImpl
 * @Description:
 * @date: 2018-07-31 18:02:58
 */
@Service
public class PwSellerReportServiceImpl extends BaseServiceImpl<PwSellerReportEntity, String> implements PwSellerReportService {

    @Autowired
    private PwSellerReportDao pwsellerreportDao;
    // 票款
    @Autowired
    private PwAccountMainTicketMoneyService accountMainTicketMoneyService;
    // 账单明细
    @Autowired
    private PwAccountListService accountListService;
    // 售票员结算单明细
    @Autowired
    private SellerReportDetailService sellerReportDetailService;

    @Override
    public IBaseDao<PwSellerReportEntity, String> getDao() {
        return pwsellerreportDao;
    }

    /*
     * @Author:  libs
     * @Date:    2018/8/6 17:50
     * @Description: 查询售票员某一天的结算单，必须字段：车站编号systemId，售票员工号sellerId，结算时间jsDate
     **/
    @Override
    public List<PwSellerReportEntity> getOneDay(PwSellerReportEntity pwSellerReportEntity) {
        return pwsellerreportDao.selectOneDay(pwSellerReportEntity);
    }

    @Override
    public PwSellerReportEntity getLatestSellaerReportEntity(String systemId) {
        return pwsellerreportDao.getSellerReportDesBySystemId(systemId);
    }

    @Override
    public ResultVO addSellerReport(String sellerId, String systemId, String account) throws Exception {
        PwSellerReportEntity newAddReportEntity = null;
        //1.根据售票员工号 查出所有与他相关的 结算单记录 ---> 条件:sellerId
        PwSellerReportEntity queryBySellerId = new PwSellerReportEntity();
        queryBySellerId.setSellerId(sellerId);

        // 获取该售票员上一笔结算单所有数据  若有则拿到时间新的一条 ( 时间倒序排 )
        List<PwSellerReportEntity> sellerReportList = pwsellerreportDao.selectList(queryBySellerId);

        if (sellerReportList.size() > 0) {
            // 上一笔最新的结算单
            PwSellerReportEntity beforeSellerReport = sellerReportList.get(0);

            // 条件起始时间 -> 上一笔结算单的结束时间
            String startTimeCondition = beforeSellerReport.getJsendDate();
            // 条件 结束时间 -> 系统当前时间
            String endTimeCondition = DateUtil.getTimeNow();

            // 1.判断这个时间段内 该售票员是否进行了票款配发操作 在T_PW_ACCOUNT_MAIN  relateOper是售票员  售票员配票款 售配  type=23
            // startTime   endTime    sellerId   type
            PwAccountMainEntity mainTickMoneyQuery = new PwAccountMainEntity();
            mainTickMoneyQuery.setRelateOper(sellerId);
            mainTickMoneyQuery.setStartTime(startTimeCondition);
            mainTickMoneyQuery.setEndTime(endTimeCondition);
            mainTickMoneyQuery.setType("23");
            List<PwAccountMainEntity> allocateTickMoneyList = accountMainTicketMoneyService.findStartAndEndTimeSellerIdMainEntity(mainTickMoneyQuery);

            // 条件成立 -> 已经配发票款;
            if (allocateTickMoneyList.size() > 0) {
                PwAccountMainEntity handInMoneyQuery = new PwAccountMainEntity();
                handInMoneyQuery.setRelateOper(sellerId);
                handInMoneyQuery.setStartTime(startTimeCondition);
                handInMoneyQuery.setEndTime(endTimeCondition);
                handInMoneyQuery.setType("14");

                // 2.判断这个时间段内 该售票员是否进行了下班交票款的操作 在T_PW_ACCOUNT_MAIN  relateOper是售票员  售票员上下班交票款 售交  type=14
                List<PwAccountMainEntity> handInTickMoneyList = accountMainTicketMoneyService.findStartAndEndTimeSellerIdMainEntity(handInMoneyQuery);
                if (handInTickMoneyList.size() > 0) {  // 条件符合 已经上下班交票款

                    // 两个条件都满足 要新增的 结算单主表数据
                    newAddReportEntity = new PwSellerReportEntity();
                    // ID
                    newAddReportEntity.setId(Tools.getNewUUID());

                    // 1.车站编号
                    newAddReportEntity.setSystemId(systemId);
                    // 2.结算单编号
                    newAddReportEntity.setReportId(generateAccountId(systemId));

                    // 3.结算时间 YYYY-MM-DD
                    newAddReportEntity.setJsDate(DateUtil.getStringDateShort());
                    // 4.结算开始时间 -->上一笔结算单的结算结束时间
                    newAddReportEntity.setJsbeginDate(beforeSellerReport.getJsendDate());
                    // 5.结算结束时间 --> 系统当前时间: yyyy-MM-dd HH:mm:ss
                    newAddReportEntity.setJsendDate(DateUtil.getTimeNow());
                    // 6.结算客值  --> 当前系统登陆用户工号
                    newAddReportEntity.setOperator(account);
                    // 7.结算售票员工号
                    newAddReportEntity.setSellerId(sellerId);

                    // 8.配送备用金 --> 票款配发里面的备用金总额--> 所有售配单-备用金总额
                    Double totalM01Issue = 0.00;
                    for (PwAccountMainEntity allcateMain : allocateTickMoneyList) {
                        // 根据 售配主表 -> 拿到所有明细 -> 拿到所有明细中的备用金 实际金额 -> 叠加
                        List<PwAccountListEntity> accountDetailList = accountListService.getListByAccountId(allcateMain.getAccountId());
                        for (PwAccountListEntity listEntity : accountDetailList) {
                            if ("M01" == listEntity.getId()) {
                                totalM01Issue = totalM01Issue + listEntity.getActMoney();
                            }
                        }
                    }
                    newAddReportEntity.setM01Issue(totalM01Issue);

                    // 9.交回备用金
                    Double totalM01Handin = 0.00;
                    for (PwAccountMainEntity handInTickMoneyMain : handInTickMoneyList) {
                        // 根据 上交票款主表 -> 拿到所有明细 -> 拿到所有明细中上交备用金 实际金额 -> 叠加
                        List<PwAccountListEntity> accountDetailList = accountListService.getListByAccountId(handInTickMoneyMain.getAccountId());
                        for (PwAccountListEntity listEntity : accountDetailList) {
                            if ("M01" == listEntity.getId()) {
                                totalM01Handin = totalM01Handin + listEntity.getActMoney();
                            }
                        }
                    }
                    newAddReportEntity.setM01Handin(totalM01Handin);
                    // 10.备用金差额 --> 交回备用金金额 - 配送备用金
                    newAddReportEntity.setM01Diff(totalM01Handin - totalM01Issue);

                    // 11.应退款金额 --> 按照系统接收时间，售票员ID统计92交易里面的交易金额+71，75交易里面的交易金额+押金+费用加上换票退票关联退票金额
                    newAddReportEntity.setReturnMoney(100.00);
                    //TODO
                    // 12.实际退款金额 --> 待定，默认为0
                    newAddReportEntity.setReturnMoneyAct(0.00);
                    // 13.操作设备号  --> 据操作员ID查询交易表，统计相关的全局设备ID字段，多个设备ID用逗号区分
                    newAddReportEntity.setDeviceId("");
                    // TODO
                    // 14.充值金额 --> 按照系统接收时间，售票员ID统计11交易里面的交易金额-按照系统接收时间，售票员ID统计79交易里面的交易金额
                    newAddReportEntity.setChargeMoney(100.00);
                    // TODO
                    // 15.超程超时现金  --> 按照系统接收时间，售票员ID统计83交易里面的费用列
                    newAddReportEntity.setCccsxj(100.00);

                    // 16.进出站更新现金 --> 按照系统接收时间，售票员ID统计89交易里面的费用列
                    newAddReportEntity.setJczgxxj(100.00);
                    //TODO
                    // 17.记名卡押金 --> 按照系统接收时间，售票员ID统计93交易里面的押金+费用
                    newAddReportEntity.setJmkyj(100.00);
                    // 18.进出站更新扣值
                    newAddReportEntity.setJczgxkz(100.00);
                    // 19.超时超程扣值
                    newAddReportEntity.setCccskz(100.00);
                    // 20.预收款金额
                    newAddReportEntity.setYsk(100.00);
                    // 21.补收票款
                    newAddReportEntity.setBspk(22200.00);
                    // 22.其它收入
                    newAddReportEntity.setOther(100.00);
                    // 23.儿童票
                    newAddReportEntity.setEtp(100L);
                    // 24.进出更新扣次
                    newAddReportEntity.setJczgxkc(100L);
                    // 25.换票售票张数
                    newAddReportEntity.setHpspzs(1000L);
                    // 26.换票售票金额
                    newAddReportEntity.setHpspje(100.00);
                    // 27.换票退票张数
                    newAddReportEntity.setHptpzs(1007878L);
                    // 28.换票退票金额
                    newAddReportEntity.setHptpje(100.00);
                    // 29.核准更新扣值
                    newAddReportEntity.setHzgxkz(100.00);
                    // 30.应收金额
                    newAddReportEntity.setMoneyShould(100.00);
                    // 31.实收金额
                    newAddReportEntity.setMoneyAct(100.00);
                    // 32.差额
                    newAddReportEntity.setDiff(100.00);

                    //上传状态 00:未上传 01:上传完成
                    newAddReportEntity.setHandleF("00");
                    pwsellerreportDao.insertSelective(newAddReportEntity);

                    // 明细内容
                    PwSellerReportDetailEntity detail1 = new PwSellerReportDetailEntity();
                    detail1.setId(Tools.getNewUUID());
                    detail1.setSystemId(systemId);
                    detail1.setSellMoney(4000.00);
                    detail1.setHandinNum(45L);
                    detail1.setIssueNum(6767L);
                    detail1.setSellNum(6837L);
                    detail1.setStatus("1");
                    detail1.setSum(90000.00);
                    detail1.setReportId(newAddReportEntity.getReportId());
                    detail1.setItemId("98");
                    PwSellerReportDetailEntity detail2 = new PwSellerReportDetailEntity();
                    detail2.setId(Tools.getNewUUID());
                    detail2.setSystemId(systemId);
                    detail2.setSellMoney(4000.00);
                    detail2.setHandinNum(6005L);
                    detail2.setIssueNum(3007L);
                    detail2.setSellNum(5000837L);
                    detail2.setStatus("1");
                    detail2.setSum(90000.00);
                    detail2.setReportId(newAddReportEntity.getReportId());
                    detail2.setItemId("99");
                    sellerReportDetailService.add(detail1);
                    sellerReportDetailService.add(detail2);

                    List<PwSellerReportDetailEntity> detailList = new ArrayList<>();
                    detailList.add(detail1);
                    detailList.add(detail2);

                } else {  // 条件不符合 没有售票员上下班交票款记录
                    return new ResultVO(false, "该售票员未进行下班上交配票款的操作，无法结算", "550");
                }
            } else {  // 条件不成立 -> 没有票款配发 -> 直接返回
                return new ResultVO(false, "该售票员未进行上班配票款的操作，无法结算", "551");
            }
        } else {
            // 该售票员没有上一笔结算单 则从现在的系统时间 向前推3天 作为起始时间
            return new ResultVO(false, "该售票员未进行上班配票款的操作，无法结算", "552");
        }
        return new ResultVO(true, "添加售票员结算单成功", "200",newAddReportEntity);
    }

    /*
     * @Author:  liyang
     * @Date:    2018/8/4  17:19
     * @Description:  生成售票员结算单 reportId
     *
     **/
    public String generateAccountId(String systemId) {
        // 查询最新的一条记录
        PwSellerReportEntity latestEntity = pwsellerreportDao.getSellerReportDesBySystemId(systemId);
        String accountYear = DateUtil.dateToString(new Date()).substring(0, 4);
        // 默认序号设置为0
        String lsatAccountNum = "0";
        if (latestEntity != null) {
            String lastAId = latestEntity.getReportId();

            // 获取最新的一条记录的年份 [倒数第10位（包含）~ 倒数第6位（不包含）)
            String year = lastAId.substring(lastAId.length() - 10, lastAId.length() - 6);
            // 如果最新的一条记录的年份等于当前年份，则新增的单据序号在此基础上 +1，否则使用默认值（重新从000001开始）
            if (accountYear.equals(year)) {
                // 取后6位
                lsatAccountNum = lastAId.substring(lastAId.length() - 6, lastAId.length());
            }
        }
        int newAccountInt = Integer.parseInt(lsatAccountNum) + 1;
        String realStringAccountInt = String.valueOf(newAccountInt);
        StringBuffer buffer = new StringBuffer();
        // 如果序号不足6位，则高位用0补齐
        for (int realLen = realStringAccountInt.length(); realLen < 6; realLen++) {
            buffer.append("0");
        }
        return "售票员结算" + accountYear + buffer + realStringAccountInt;
    }
}